
import { _decorator, Label, Button, Sprite, Node, Prefab } from 'cc';
import { v3 } from 'cc';
import { UITransform } from 'cc';
import { v2 } from 'cc';
import { BaseView } from '../../../../scripts/libs/rxjs/cc3/BaseView';
import { EditorBlock } from './EditorBlock';
import { ReactiveProperty } from '../../../../scripts/libs/rxjs/cc3/ReactiveProperty';
import { BindButton } from '../../../../scripts/libs/rxjs/cc3/BindButton';
import { BindDragWithLimited, BindNodeEvent, BindNodeTouch } from '../../../../scripts/libs/rxjs/cc3/BindNode';
import { lm } from '../../LobbyManager';
import { EditorColorItem } from './EditorColorItem';
import { gm } from '../../../../scripts/managers/GameManager';
import { Color } from 'cc';
import { color } from 'cc';
import { EditorStageView } from './EditorStageView';
import { Graphics } from 'cc';
import { AxisLockTypeTxt, Colors, dirArrowTxt } from '../../game/basic';
import { lerp } from 'cc';
import { NodeEventType } from 'cc';
import { Toggle } from 'cc';
import { BindToggle } from '../../../../scripts/libs/rxjs/cc3/BindToggle';
import { KeyDown } from '../../../../scripts/libs/rxjs/cc3/KeyEvent';
import { KeyCode } from 'cc';
import { MergeWithTimer } from '../../../../scripts/libs/rxjs/cc3/Merge';
import { EditorInspectorNumber } from './EditorInspectorNumber';
import { instantiate } from 'cc';
import { EditorInspectorString } from './EditorInspectorString';
const { ccclass, property } = _decorator;


const _v20 = v2();
const _v30 = v3();

@ccclass('EditorBlockInspector')
export class EditorBlockInspector extends BaseView {

    // blockInspectorMap: Map<number, EditorBlockInspector> = null;
    editorStageView: EditorStageView = null;

    editorBlock = ReactiveProperty.Create<EditorBlock>(null);

    pined = ReactiveProperty.Create(false);

    @property(Node)
    focusNode: Node = null;

    @property(Button)
    snailButton: Button = null;

    @property(Sprite)
    snailSprite: Sprite = null;

    @property(Label)
    posIdLabel: Label = null;

    @property(Button)
    posIdButton: Button = null;

    @property(Label)
    blockIdLabel: Label = null;

    @property(Label)
    axisLockLabel: Label = null;

    @property(Button)
    axisLockButton: Button = null;

    @property(Button)
    closeButton: Button = null;

    @property(Button)
    deleteButton: Button = null;

    @property(EditorColorItem)
    editorColorItem: EditorColorItem = null;

    @property(Label)
    layerLabel: Label = null;

    @property(Button)
    moveBackButton: Button = null;

    @property(Button)
    moveFrontButton: Button = null;

    @property(EditorInspectorNumber)
    groupInspectorNumber: EditorInspectorNumber = null;

    @property(Button)
    groupIdButton: Button = null;

    @property(Graphics)
    graphics: Graphics = null;

    @property(Sprite)
    circleDotSprite: Sprite = null;

    focus = ReactiveProperty.Create(false);

    @property(Prefab)
    crosshairPrefab: Prefab = null;

    @property(EditorInspectorNumber)
    iceInspectorNumber: EditorInspectorNumber = null;

    @property(EditorInspectorNumber)
    blindInspectorNumber: EditorInspectorNumber = null;

    @property(EditorInspectorNumber)
    noBlindTxtInspectorNumber: EditorInspectorNumber = null;

    @property(EditorColorItem)
    editorLockerColorItem: EditorColorItem = null;

    @property(EditorInspectorString)
    axisLockParamInspectorString: EditorInspectorString = null;

    willBind(): void {
        this.editorLockerColorItem.txtFilter = data => `(L)ocker:${data}`;
    }

    useObserves() {
        return [
            this.pined.subscribe(this.refreshPined.bind(this)),
            this.editorBlock.subscribe(this.refresh.bind(this)),
            BindButton(this.snailButton).subscribe(this.snailButtonClicked.bind(this)),
            BindButton(this.posIdButton).subscribe(this.posIdButtonClicked.bind(this)),
            BindButton(this.axisLockButton).subscribe(this.axisLockButtonClicked.bind(this)),

            BindButton(this.moveBackButton).subscribe(this.moveBackButtonClicked.bind(this)),
            BindButton(this.moveFrontButton).subscribe(this.moveFrontButtonClicked.bind(this)),

            BindButton(this.closeButton).subscribe(this.closeButtonClicked.bind(this)),
            BindButton(this.deleteButton).subscribe(this.deleteButtonClicked.bind(this)),

            BindNodeTouch(this.groupIdButton.node).subscribe(_ => {
                if (_.type == Node.EventType.TOUCH_START) {
                    this.groupIdButtonTouchStart();
                }
            }),

            this.editorColorItem.asButtonClickObservable().subscribe(this.colorButtonClicked.bind(this)),
            this.editorLockerColorItem.asButtonClickObservable().subscribe(this.lockerColorButtonClicked.bind(this)),

            BindNodeEvent(this.node, NodeEventType.TRANSFORM_CHANGED, true).subscribe(this.refreshGraphics.bind(this)),
            KeyDown().subscribe((_: KeyCode) => {
                if (this.focus.value) {
                    if (_ == KeyCode.KEY_C) {
                        this.colorButtonClicked();
                    } if (_ == KeyCode.KEY_L) {
                        this.lockerColorButtonClicked();
                    } else if (_ == KeyCode.KEY_N) {
                        this.blindToggleChanged();
                    } else if (_ == KeyCode.KEY_A) {
                        this.axisLockButtonClicked();
                    } else if (_ == KeyCode.DELETE) {
                        this.deleteButtonClicked();
                    } else if (_ == KeyCode.ARROW_UP) {
                        this.moveFrontButtonClicked();
                    } else if (_ == KeyCode.ARROW_DOWN) {
                        this.moveBackButtonClicked();
                    } else if (_ == KeyCode.KEY_G) {
                        this.groupIdButtonTouchStart();
                    }
                }
            }),
            gm.unfocusAllCommand.subscribe(_ => {
                this.focus.value = false;
            }),
            this.focus.subscribe(_ => this.focusNode.active = _),
            BindNodeTouch(this.node).subscribe(_ => {
                if (_.type == Node.EventType.TOUCH_START) {
                    this.focusSelf();
                    this.node.setSiblingIndex(-1);
                }
            }),

            this.groupInspectorNumber.changedCommand.subscribe(_ => this.editorStageView.remakeStageInfo()),
            this.iceInspectorNumber.changedCommand.subscribe(_ => this.editorStageView.remakeStageInfo()),
            this.blindInspectorNumber.changedCommand.subscribe(_ => this.editorStageView.remakeStageInfo()),
            this.noBlindTxtInspectorNumber.changedCommand.subscribe(_ => this.editorStageView.remakeStageInfo()),
            this.axisLockParamInspectorString.changedCommand.subscribe(_ => this.editorStageView.remakeStageInfo()),
        ]
    }

    start() {
        BindDragWithLimited(this.node, lm.uiRoot.camera, () => {
            let size = this.node.parent.getComponent(UITransform).contentSize;
            return { x: [-size.width / 2, size.width / 2], y: [-size.height / 2, size.height / 2] }
        }).subscribe(_ => {
            if (_.type == 'touch-start') {
                this.node.setSiblingIndex(-1);
            }
        }).addTo(this.node);
        this.focusSelf();
    }

    focusSelf() {
        gm.unfocusAllCommand.execute();
        this.focus.value = true;
        // gm.editQueueSelected.value = this.index.value;
    }

    refreshPined() {
        if (this.pined.value) {
            this.snailSprite.node.setRotationFromEuler(v3(0, 0, 0));
            this.snailSprite.color = Color.GREEN;
        } else {
            this.snailSprite.node.setRotationFromEuler(v3(0, 0, -45));
            this.snailSprite.color = color().fromHEX('#6c6c6c');
        }
    }

    _refreshing = false;
    refresh() {
        if (this.editorBlock.value == null) {
            this.posIdLabel.string = 'n/a';
            this.blockIdLabel.string = 'n/a';
            return;
        }
        if (this._refreshing) return;
        this._refreshing = true;
        this.posIdLabel.string = `posId: ${this.editorBlock.value.posId.value}`;
        this.blockIdLabel.string = `blockId: ${this.editorBlock.value.blockId.value}`;
        this.editorColorItem.colorId = this.editorBlock.value.colorId;
        this.editorLockerColorItem.colorId = this.editorBlock.value.lockerColor.value;
        this.axisLockLabel.string = `axisLock:${AxisLockTypeTxt[this.editorBlock.value.axisLock]}`;

        this.layerLabel.string = `layer: ${this.editorBlock.value.layer.value}`;

        this.groupInspectorNumber.setGetRP(() => this.editorBlock.value.group);
        this.iceInspectorNumber.setGetRP(() => this.editorBlock.value.ice);
        this.blindInspectorNumber.setGetRP(() => this.editorBlock.value.blind);
        this.noBlindTxtInspectorNumber.setGetRP(() => this.editorBlock.value.noBlindTxt);
        this.axisLockParamInspectorString.setGetRP(() => this.editorBlock.value.axisLockParam);

        this.refreshGraphics();
        this._refreshing = false;
    }

    snailButtonClicked() {
        this.log('@snailButtonClicked');
        this.pined.value = !this.pined.value;
    }

    posIdButtonClicked() {
        // if (gm.editPosSelected.value != null) {
        //     this.editorStageView.moveBlock(this.editorBlock.value.posId.value, gm.editPosSelected.value);
        //     this.editorBlock.again();
        //     this.editorStageView.remakeStageInfo();
        // }
    }

    axisLockButtonClicked() {
        this.editorBlock.value.axisLock = (this.editorBlock.value.axisLock + 1) % 3;
        this.editorBlock.again();
        this.editorStageView.remakeStageInfo();
    }

    blindToggleChanged() {
        if (this._refreshing) return;
        this.editorBlock.again();
        this.editorStageView.remakeStageInfo();
    }

    colorButtonClicked() {
        this.log('@colorButtonClicked');
        if (gm.editColorSelected.value != null) {
            this.editorBlock.value.colorId = gm.editColorSelected.value;
            this.editorBlock.again();
            this.editorStageView.remakeStageInfo();
        }
    }

    lockerColorButtonClicked() {
        this.log('lockerColorButtonClicked');
        if (gm.editColorSelected.value != null) {
            this.editorBlock.value.lockerColor.value = gm.editColorSelected.value;
            this.editorBlock.again();
            this.editorStageView.remakeStageInfo();
        }
    }

    closeButtonClicked() {
        this.editorStageView.blockInspectorMap.delete(this.editorBlock.value.blockId.value);
        this.editorBlock.value = null;
        this.node.destroy();
    }

    deleteButtonClicked() {
        this.editorStageView.removeBlock(this.editorBlock.value.blockId.value);
        this.editorStageView.remakeStageInfo();
    }

    refreshGraphics() {
        if (this.graphics && this.editorBlock.value) {
            this.editorBlock.value.node.getWorldPosition(_v30);
            _v30.subtract(this.graphics.node.worldPosition);
            let p1 = v2(0, _v30.y / 3);
            let p2 = v2(_v30.x, _v30.y * 2 / 3);
            let p3 = v2(_v30.x, _v30.y);
            this.graphics.clear();
            this.graphics.moveTo(0, 0);
            this.graphics.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
            this.graphics.stroke();

            if (this.editorBlock.value.ice.value > 0) {
                this.graphics.strokeColor = Color.WHITE;
                this.circleDotSprite.color = Color.WHITE;
            } else {
                this.graphics.strokeColor = Colors[this.editorBlock.value.colorId];
                this.circleDotSprite.color = Colors[this.editorBlock.value.colorId];
            }
        }
    }

    moveBackButtonClicked() {
        this.editorBlock.value.layer.value--;
        this.editorBlock.again();
        this.editorStageView.reorderBlocks();
        this.editorStageView.remakeStageInfo();
    }

    moveFrontButtonClicked() {
        this.editorBlock.value.layer.value++;
        this.editorBlock.again();
        this.editorStageView.reorderBlocks();
        this.editorStageView.remakeStageInfo();
    }

    groupIdButtonTouchStart() {
        let node = instantiate(this.crosshairPrefab);
        node.setParent(lm.uiRoot.tierFrontNode);
        node.setWorldPosition(this.groupIdButton.node.worldPosition);
        this.editorStageView.groupIdSelectIndicator.value = node;

    }

}


